package main

import (
	"context"
	"flag"
	"fmt"
	"github.com/golang/glog"
	"net/http"
	"os"
	"os/signal"
	"time"
)

//设置一个拦截器，用于处理每次请求的header，并将version环境变量写到header中
func handleIterceptor(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		//读取请求中的header，并写入返回请求中
		for key, outerval := range r.Header {
			for _, innerval := range outerval {
				//glog.Infof("key=%s,val=%s\n",key,innerval)
				w.Header().Set(key, innerval)
			}
		}
		//打印源ip和http返回码
		w.WriteHeader(200)
		glog.Infof("remoteaddr=%s,httpcode=%d\n", r.RemoteAddr, 200)
		//写入version到header
		version := os.Getenv("version")
		w.Header().Set("version", version)
		handler(w, r)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "hello")
}

func healthz(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "ok")
}
func main() {
	//解析参数，用于控制glog的日志输出
	flag.Parse()
	//退出时，保证日志的完整性
	defer glog.Flush()
	// 自定义路由
	mux := http.NewServeMux()
	mux.HandleFunc("/healthz", handleIterceptor(healthz))
	mux.HandleFunc("/", handleIterceptor(handler))

	//设置服务器,孟老师ppt里面，没有明确定义端口，这里选用8080
	srv := http.Server{
		Addr:    ":8080",
		Handler: mux,
	}

	// 确保优雅的退出
	processed := make(chan struct{})
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		<-c

		ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
		defer cancel()
		//为server设置一个用于优雅退出的上下文
		if err := srv.Shutdown(ctx); nil != err {
			glog.Fatalf("server shutdown failed, err: %v\n", err)
		}
		glog.Infoln("server gracefully shutdown")
		close(processed)
	}()

	// 启动服务器
	err := srv.ListenAndServe()
	if http.ErrServerClosed != err {
		glog.Fatalf("server not gracefully shutdown, err :%v\n", err)
	}

	// 利用chan阻塞主进程
	<-processed
}
